package com.laoye.controller;

import com.laoye.bean.User;
import com.laoye.dto.*;
import com.laoye.service.AliyunOSSService;
import com.laoye.service.UserService;
import com.laoye.util.JwtUtil;
import com.laoye.util.Page;
import com.laoye.util.Result;
import com.laoye.util.ThreadLocal;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@CrossOrigin
@RequestMapping("user")
public class UserController {
    @Autowired
    UserService userService;
    @Autowired
    private AliyunOSSService aliyunOSSService;
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    StringRedisTemplate redis;

    @GetMapping("emailCode/{email}")
    public Result<String> getEmailCode(@PathVariable("email") String email) {
        userService.sendEmailCode(email);
        return Result.success("验证码已发送，请查收！");
    }

    /**
     * 获取当前用户信息
     *
     * @return 获取当前用户信息
     */
    @GetMapping("info")
    public Result<User> getUserInfo() {
        return Result.success(userService.getUserById());
    }

    /**
     * 获取当前用户头像
     *
     * @return 获取当前用户头像
     */
    @GetMapping("url")
    public Result<String> getAvatarUrl() {
        String avatarUrl = userService.getAvatarUrl(ThreadLocal.getCurrentId());
        return Result.success("", avatarUrl);
    }

    /**
     * 头像上传
     *
     * @param file 头像文件
     * @return 返回上传成功，并返回上传后的文件路径
     */
    @PostMapping("avatar")
    public Result<String> avatarUpload(@RequestParam("file") MultipartFile file) throws Exception {

        String uploadFile = aliyunOSSService.uploadFile(file);
        userService.updateAvatar(uploadFile, ThreadLocal.getCurrentId());
        return Result.success("头像上传成功", uploadFile);

    }

    /**
     * 修改密码逻辑
     *
     * @param pwdEditDTO 前端传来的修改密码信息
     * @return 返回修改成功
     */
    @PutMapping("updatePassword")
    public Result<String> updatePassword(@RequestBody PwdEditDTO pwdEditDTO) {
        userService.updatePassword(pwdEditDTO);
        return Result.success("密码修改成功，请重新登录！");
    }

    /**
     * 获取用户名
     *
     * @return 返回用户名，用于前端修改密码和信息时显示
     */
    @GetMapping("getUsername")
    public Result<String> updatePassword() {
        String username = userService.findUsername(ThreadLocal.getCurrentId());
        return Result.success("", username);
    }

    /**
     * 修改用户信息
     *
     * @param userEditDTO 用户信息
     * @return 返回修改成功
     */
    @PutMapping("edit")
    public Result<String> updatePassword(@RequestBody UserEditDTO userEditDTO) {
        userService.editUser(userEditDTO);
        return Result.success("修改成功");
    }


    /**
     * 登录
     *
     * @param loginDTO 登录信息
     * @return 返回登录成功，并返回token
     */
    @PostMapping("login")
    public Result<String> login(@RequestBody LoginDTO loginDTO) {
        User user = userService.login(loginDTO);
        Map<String, Object> claims = new HashMap<>();
        claims.put("username", user.getUsername());
        claims.put("id", user.getId());
        claims.put("role", "user");
        String token = jwtUtil.generateToken(claims, user.getUsername());
        redis.opsForValue().set("UserJWTToken" + user.getId() + ":", token,
                43200,
                TimeUnit.SECONDS);
        return Result.success("用户登录成功", token);
    }

    /**
     * 注册
     *
     * @param registerDTO 注册信息
     * @return 返回注册成功
     */
    @PostMapping("register")
    public Result<String> register(@RequestBody RegisterDTO registerDTO) {
        userService.register(registerDTO);
        return Result.success("注册成功");
    }

    /**
     * 登出
     *
     * @return 登出成功
     */
    @GetMapping("logout")
    public Result<String> logout() {
        userService.logout();
        return Result.success("注销成功");
    }

    /**
     * 分页查询用户
     *
     * @param keyword  搜索框输入的内容
     * @param pageNum  页数
     * @param pageSize 每页数量
     * @return 返回分页后信息，result进行包装
     */
    @GetMapping("page")
    public Result<Page<UserPageDTO>> getUsersPage(
            @RequestParam(required = false) String keyword,
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize
    ) {
        Page<UserPageDTO> usersPage = userService.getUsersPage(keyword, pageNum, pageSize);
        //users page已经包含总记录数和总页数
        return Result.success(usersPage);
    }
}
